import {isFunction} from "@vue/shared"
import {onUpdated} from "vue"

const addErrorTip = (ele, checkValue) => {
    const errorTip = document.createElement("div")
    errorTip.classList = "use-data-check-error-tip animate__animated animate__faster animate__fadeInRight"
    errorTip.innerText = checkValue
    ele.parentElement.append(errorTip)
    ele.parentElement.classList.add("use-data-check-error")
    ele.onfocus = () => {
        ele.onfocus = null
        errorTip.remove()
        ele.parentElement.classList.remove("use-data-check-error")
    }
    const origOnclick = ele.onclick
    ele.onclick = () => {
        ele.onclick = origOnclick
        if (isFunction(origOnclick)) origOnclick()
        errorTip.remove()
        ele.parentElement.classList.remove("use-data-check-error")
    }
}

const observerCallback = (entries) => {
    entries.forEach((entry) => {
        if (!entry.isIntersecting) {
            const ele = entry.target
            observer.unobserve(ele)
            ele.parentElement.querySelector(".use-data-check-error-tip")?.remove()
            ele.parentElement.classList.remove("use-data-check-error")
        }
    })
}

const observer = new IntersectionObserver(observerCallback)

const checkElement = (ele, checkValue, invisibleAutoClearErrorTip) => {
    let pass = true
    const value = ele.nodeName === 'DIV' ? ele.innerText : ele.value
    // 值为空,checkValue不是函数并且存在校验内容,则校验不通过
    if (!value && checkValue && !isFunction(checkValue)) {
        if (invisibleAutoClearErrorTip) observer.observe(ele)
        pass = false
        if (!ele.parentElement.querySelector(".use-data-check-error-tip")) addErrorTip(ele, checkValue)
    } else if (checkValue && isFunction(checkValue)) {
        // 有值，并且checkValue是个函数
        const result = checkValue(value)
        if (result) {
            if (invisibleAutoClearErrorTip) observer.observe(ele)
            pass = false
            if (!ele.parentElement.querySelector(".use-data-check-error-tip")) addErrorTip(ele, result)
        }
    }
    return pass
}

const useDataCheck = (valiateRule = {}) => {
    const update = () => {
        // 添加必填标签
        for (const ele of document.querySelectorAll("[checklabel]")) {
            if (ele.querySelector(".checklabel")) continue
            const checklabel = document.createElement("span")
            checklabel.classList = "checklabel red-color"
            checklabel.innerText = "*"
            ele.append(checklabel)
        }
    }

    onUpdated(update)

    const check = (invisibleAutoClearErrorTip = true) => {
        let pass = true
        for (const ele of Array.from(document.querySelectorAll("[check]")).filter(div => isElementVisible(div))) {
            const checkName = ele.getAttribute("check")
            const checkValue = valiateRule[checkName]
            if (!checkElement(ele, checkValue, invisibleAutoClearErrorTip)) pass = false
        }
        return new Promise((resolve) => {
            if (pass) resolve()
        })
    }

    function isElementVisible(element) {
        let currentElement = element;
        while (currentElement) {
            const style = window.getComputedStyle(currentElement);
            if (style.display === 'none') {
                return false;
            }
            currentElement = currentElement.parentElement;
        }
        return true;
    }

    const clear = (delay) => {
        const clearError = () => {
            for (const ele of document.querySelectorAll("[check]")) {
                const checkName = ele.getAttribute("check")
                if (valiateRule[checkName]) ele.parentElement.querySelector(".use-data-check-error-tip")?.remove()
                ele.parentElement.classList.remove("use-data-check-error")
            }
        }

        if (delay) {
            setTimeout(clearError, delay)
        } else {
            clearError()
        }
    }

    return {check, clear}
}

export default useDataCheck